package com.txc.pay.pay.impl;

import cn.hutool.core.util.StrUtil;
import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.Config;
import com.alipay.easysdk.payment.common.models.AlipayTradeCloseResponse;
import com.alipay.easysdk.payment.common.models.AlipayTradeFastpayRefundQueryResponse;
import com.alipay.easysdk.payment.common.models.AlipayTradeQueryResponse;
import com.alipay.easysdk.payment.common.models.AlipayTradeRefundResponse;
import com.txc.pay.config.AliPayConfig;
import com.txc.pay.entity.AccountEntity;
import com.txc.pay.enums.PayType;
import com.txc.pay.pay.ThirdPay;
import com.txc.pay.service.IAccountService;

import jakarta.annotation.Resource;
import java.util.UUID;

/**
 * @ClassName: AliPay
 * @Description: 支付宝支付抽象类
 * @Author: TXC
 * @Date: 2023-12-26 15:03
 **/
public abstract class AliPay implements ThirdPay {
    @Resource
    IAccountService accountService;
    /**
     * @param outRefundNo 商户退款订单号
     * @param refund      退款金额（单位为元，支持两位小数）
     * @param total       原订单总金额（单位为元，支持两位小数）
     * @return
     */
    @Override
    public String refund(String outRefundNo, String refund, String total, String accountId) {
        aliConfig(accountId);
        AlipayTradeRefundResponse response;
        try {
            response = Factory.Payment.Common().refund(outRefundNo, refund);
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
        return response.getHttpBody();
    }

    @Override
    public String queryByOutRefundNo(String outRefundNo, String accountId) {
        aliConfig(accountId);
        AlipayTradeFastpayRefundQueryResponse response;
        try {
            response = Factory.Payment.Common().queryRefund(outRefundNo, UUID.randomUUID().toString());
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
        return response.getHttpBody();
    }
    @Override
    public String queryOrderById(String transactionId, String accountId) {
        return "支付宝暂时不支持此类查询！";
    }

    @Override
    public String queryOrderByOutTradeNo(String outTradeNo, String accountId) {
        aliConfig(accountId);
        AlipayTradeQueryResponse response;
        try {
            response = Factory.Payment.Common().query(outTradeNo);
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
        return response.getBody();
    }

    @Override
    public String closeOrder(String outTradeNo, String accountId) {
        aliConfig(accountId);
        AlipayTradeCloseResponse response;
        try {
            response = Factory.Payment.Common().close(outTradeNo);
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage(), e);
        }
        return response.getHttpBody();
    }

    public Config aliConfig(String accountId) {
        Config config = new Config();
        AccountEntity account = getAccount(accountId);
        AliPayConfig aliPayConfig = aliPayConfig(account);
        config.protocol = aliPayConfig.getProtocol();
        config.gatewayHost = aliPayConfig.getGatewayHost();
        config.signType = aliPayConfig.getSignType();
        config.appId = aliPayConfig.getAppId();
        config.merchantPrivateKey = account.formatPrivateKey();
        config.alipayPublicKey = aliPayConfig.getAliPayPublicKey();
        config.notifyUrl = aliPayConfig.getNotifyUrl();
        config.encryptKey = aliPayConfig.getEncryptKey();
        Factory.setOptions(config);
        return config;
    }

    public AliPayConfig aliPayConfig(AccountEntity account) {
        try {
            return AliPayConfig.jsonToBean(account.getParam());
        } catch (Exception e) {
            throw new NullPointerException("请先配置微信支付参数");
        }
    }

    public AccountEntity getAccount(String accountId) {
        AccountEntity account;
        if (StrUtil.isNotEmpty(accountId)) {
            account = accountService.getById(accountId);
        } else {
            account = accountService.obtainDefaultAccount(PayType.WECHAT.getValue());
        }
        return account;
    }
}
